home *** CD-ROM | disk | FTP | other *** search
- #ifndef VMS
- ERROR -- CKVCON.C is used only on the OpenVMS(tm) Operating System
- #endif /* VMS */
- #define CONN_OS_ARCH_STRING \
- "Connect Command 5A(029) 11 Oct 92";
- #ifdef __ALPHA
- /* do nothing */
- #else
- # ifdef VAX
- # module ckvcon "5.0-029"
- # else
- #ifndef __GNUC__
- ERROR -- CKVCON.C unknown architecture, neither VAX(tm) nor Alpha
- # endif /* __GNUC__ */
- # endif /* VAX */
- #endif /* __ALPHA */
-
- char *connv = CONN_OS_ARCH_STRING;
-
- /* C K V C O N -- Dumb terminal connection to remote system, for VMS */
- /*
- Author: Frank da Cruz (fdc@columbia.edu, FDCCU@CUVMA.BITNET),
- Columbia University Academic Information Systems, New York City.
-
- Copyright (C) 1985, 1993, Trustees of Columbia University in the City of New
- York. The C-Kermit software may not be, in whole or in part, licensed or
- sold for profit as a software product itself, nor may it be included in or
- distributed with commercial products or otherwise distributed by commercial
- concerns to their clients or customers without written permission of the
- Office of Kermit Development and Distribution, Columbia University. This
- copyright notice must not be removed, altered, or obscured.
- */
- /*
- * Orignally adapted from the UNIX C-Kermit CONNECT module by S. Rubenstein
- * for systems without fork(). This version of conect() uses contti(&c, &src)
- * to return when a character is available from either the console or the comm
- * line, to allow sending/receiving without breaking connection.
- *
- * Edit by
- *
- * 010 06-Mar-1989 mab General cleanup
- * 011 23-Mar-1989 mab Clean up doesc() code. Add malloc() in place of
- * static buffer space. Also increase buffer space.
- * 012 27-Sep-1989 mab Add XON sequence.
- * 013 30-Mar-1991 fdc Add so/si, character set translation.
- * 014 06-Apr-1991 fdc Adapted for TGV MultiNet TCP/IP connections.
- * 015 21-Jun-1991 tmk Cleaned up typo in session logging display.
- * 016 28-Nov-1991 fdc "Back at <hostname>", disallow CONNECT in background
- * 017 25-Dec-1991 fdc Added support for NOPUSH, added "Hanging up" message
- * 018 11-Jan-1992 fdc Added support for key mapping
- * 019 27-Jan-1992 fdc Added support for ANSI escape sequence recognition
- * 020 00-May-1992 fdc Rewrote conect() to used buffered i/o.
- * 021 10-Jun-1992 fdc Added support for Wollongong WIN/TCP from Ray Hunter.
- * Fix messed-up help message.
- * 022 20-Jun-1992 fdc Fixed handling of CR on TELNET sessions.
- * 023 28-Jun-1992 fdc Cosmetic cleanup of "Connecting..." message.
- * 024 12-Jul-1992 fdc Added mdmhup() feature (see ckudia.c).
- * 025 29-Jul-1992 fdc Grouped TELNET IP and AYT into single writes.
- * 026 13-Aug-1992 fdc Added support for SET TELNET NEWLINE-MODE.
- * 027 05-Sep-1992 lt Added architecture ifdefs for OpenVMS, Alpha, at top.
- * 028 08-Sep-1992 fdc Separated input and output SO/SO shift states.
- * 029 11-Oct-1992 fdc Reduce modem-vs-net confusion in ttopen() calls.
- */
-
- #include "ckcdeb.h"
- #include "ckcasc.h"
- #include "ckcker.h"
- #include "ckcnet.h"
- #include "ckvvms.h"
- #ifndef NOCSETS
- #include "ckcxla.h" /* Character set translation */
- #endif /* NOCSETS */
- #include <stdio.h>
- #include <ctype.h>
- #include <signal.h>
- #include <setjmp.h>
-
- static int src; /* Where input character came from */
-
- extern int local, speed, escape, duplex, parity, flow, seslog, mdmtyp, batch;
- extern int cmask, cmdmsk, debses, sosi, ttyfd, what, quiet, backgrd, tnlm,
- tt_crd, tn_nlm;
- extern char ttname[], sesfil[], myhost[];
-
- #ifndef NOICP /* Keyboard mapping */
- #ifndef NOSETKEY
- extern KEY *keymap; /* Single-character key map */
- extern MACRO *macrotab; /* Key macro pointer table */
- static MACRO kmptr = NULL; /* Pointer to current key macro */
- #endif /* NOSETKEY */
- #endif /* NOICP */
-
- /* Network support */
- extern int ttnproto, /* Virtual terminal protocol */
- network, /* Network connection active */
- nettype; /* Network type */
- #ifdef TNCODE
- /* Telnet-only variables */
- extern int tn_init; /* Telnet initialized flag */
- #endif /* TNCODE */
-
- #ifndef NOCSETS
- #ifdef CK_ANSIC
- extern CHAR (*xls[MAXTCSETS+1][MAXFCSETS+1])(CHAR); /* Character set */
- extern CHAR (*xlr[MAXTCSETS+1][MAXFCSETS+1])(CHAR); /* translation functions */
- static CHAR (*sxo)(CHAR); /* Local translation functions */
- static CHAR (*rxo)(CHAR); /* for output (sending) terminal chars */
- static CHAR (*sxi)(CHAR); /* and for input (receiving) terminal chars. */
- static CHAR (*rxi)(CHAR);
- #else
- extern CHAR (*xls[MAXTCSETS+1][MAXFCSETS+1])(); /* Character set */
- extern CHAR (*xlr[MAXTCSETS+1][MAXFCSETS+1])(); /* translation functions. */
- static CHAR (*sxo)(); /* Local translation functions */
- static CHAR (*rxo)(); /* for output (sending) terminal chars */
- static CHAR (*sxi)(); /* and for input (receiving) terminal chars. */
- static CHAR (*rxi)();
- #endif /* CK_ANSIC */
- extern int language; /* Current language. */
- extern struct csinfo fcsinfo[]; /* File character set info */
- extern int tcsr, tcsl; /* Terminal character sets, remote & local. */
- static int langsv; /* Remember language */
- static int tcs; /* Intermediate (xfer) char set */
-
- _PROTOTYP( VOID doesc, (unsigned char) );
-
- #ifndef NOESCSEQ
- /*
- As of edit 178, the CONNECT command will skip past ANSI escape sequences
- to avoid translating the characters within them. This allows the CONNECT
- command to work correctly when connected to a remote host that uses a
- 7-bit ISO 646 national character set, in which characters like '[' would
- normally be translated into accented characters, ruining the terminal's
- interpretation (and generation) of escape sequences.
-
- Escape sequences of non-ANSI/ISO-compliant terminals are not handled.
- */
- #ifndef SKIPESC
- #define SKIPESC
- #endif /* SKIPESC */
- /*
- States for the escape-sequence recognizer.
- */
- #define ES_NORMAL 0 /* Normal, not in escape sequence */
- #define ES_GOTESC 1 /* Current character is ESC */
- #define ES_ESCSEQ 2 /* Inside an escape sequence */
- #define ES_GOTCSI 3 /* Inside a control sequence */
- #define ES_STRING 4 /* Inside OSC, PM, or APC string */
- #define ES_TERMIN 5 /* 1st char of string terminator */
-
- static int
- skipesc = 0, /* Skip over ANSI escape sequences */
- inesc = ES_NORMAL; /* State of sequence recognizer */
- /*
- ANSI escape sequence handling. Only the 7-bit form is treated, because
- translation is not a problem in the 8-bit environment, in which all GL
- characters are ASCII and no translation takes place. So we don't check
- for the 8-bit single-character versions of CSI, DCS, OSC, APC, or ST. Here
- is the ANSI sequence recognizer state table, followed by the code that
- implements it.
-
- Definitions:
- CAN = Cancel 01/08 Ctrl-X
- SUB = Substitute 01/10 Ctrl-Z
- DCS = Device Control Sequence 01/11 05/00 ESC P
- CSI = Control Sequence Introducer 01/11 05/11 ESC [
- ST = String Terminator 01/11 05/12 ESC \
- OSC = Operating System Command 01/11 05/13 ESC ]
- PM = Privacy Message 01/11 05/14 ESC ^
- APC = Application Program Command 01/11 05/15 ESC _
-
- ANSI escape sequence recognizer:
-
- State Input New State ; Commentary
-
- NORMAL (start) ; Start in NORMAL state
-
- (any) CAN NORMAL ; ^X cancels
- (any) SUB NORMAL ; ^Z cancels
-
- NORMAL ESC GOTESC ; Begin escape sequence
- NORMAL other ; NORMAL control or graphic character
-
- GOTESC ESC ; Start again
- GOTESC [ GOTCSI ; CSI
- GOTESC P STRING ; DCS introducer, consume through ST
- GOTESC ] STRING ; OSC introducer, consume through ST
- GOTESC ^ STRING ; PM introducer, consume through ST
- GOTESC _ STRING ; APC introducer, consume through ST
- GOTESC 0..~ NORMAL ; 03/00 through 17/14 = Final character
- GOTESC other ESCSEQ ; Intermediate or ignored control character
-
- ESCSEQ ESC GOTESC ; Start again
- ESCSEQ 0..~ NORMAL ; 03/00 through 17/14 = Final character
- ESCSEQ other ; Intermediate or ignored control character
-
- GOTCSI ESC GOTESC ; Start again
- GOTCSI @..~ NORMAL ; 04/00 through 17/14 = Final character
- GOTCSI other ; Intermediate char or ignored control char
-
- STRING ESC TERMIN ; Maybe have ST
- STRING other ; Consume all else
-
- TERMIN \ NORMAL ; End of string
- TERMIN other STRING ; Still in string
- */
- /*
- chkaes() -- Check ANSI Escape Sequence.
- Call with EACH character in input stream.
- Sets global inesc variable according to escape sequence state.
- */
- VOID
- #ifdef CK_ANSIC
- chkaes(char c)
- #else
- chkaes(c) char c;
- #endif /* CK_ANSIC */
- /* chkaes */ {
-
- if (c == CAN || c == SUB) /* CAN and SUB cancel any sequence */
- inesc = ES_NORMAL;
- else /* Otherwise */
- switch (inesc) { /* enter state switcher */
-
- case ES_NORMAL: /* NORMAL state */
- if (c == ESC) /* Got an ESC */
- inesc = ES_GOTESC; /* Change state to GOTESC */
- break; /* Otherwise stay in NORMAL state */
-
- case ES_GOTESC: /* GOTESC state */
- if (c == '[') /* Left bracket after ESC is CSI */
- inesc = ES_GOTCSI; /* Change to GOTCSI state */
- else if (c > 057 && c < 0177) /* Final character '0' thru '~' */
- inesc = ES_NORMAL; /* Back to normal */
- else if (c == 'P' || (c > 0134 && c < 0140)) /* P, [, ^, or _ */
- inesc = ES_STRING; /* Switch to STRING-absorption state */
- else if (c != ESC) /* ESC in an escape sequence... */
- inesc = ES_ESCSEQ; /* starts a new escape sequence */
- break; /* Intermediate or ignored ctrl char */
-
- case ES_ESCSEQ: /* ESCSEQ -- in an escape sequence */
- if (c > 057 && c < 0177) /* Final character '0' thru '~' */
- inesc = ES_NORMAL; /* Return to NORMAL state. */
- else if (c == ESC) /* ESC ... */
- inesc = ES_GOTESC; /* starts a new escape sequence */
- break; /* Intermediate or ignored ctrl char */
-
- case ES_GOTCSI: /* GOTCSI -- In a control sequence */
- if (c > 077 && c < 0177) /* Final character '@' thru '~' */
- inesc = ES_NORMAL; /* Return to NORMAL. */
- else if (c == ESC) /* ESC ... */
- inesc = ES_GOTESC; /* starts over. */
- break; /* Intermediate or ignored ctrl char */
-
- case ES_STRING: /* Inside a string */
- if (c == ESC) /* ESC may be 1st char of terminator */
- inesc = ES_TERMIN; /* Go see. */
- break; /* Absorb all other characters. */
-
- case ES_TERMIN: /* May have a string terminator */
- if (c == '\\') /* which must be backslash */
- inesc = ES_NORMAL; /* If so, back to NORMAL */
- else /* Otherwise */
- inesc = ES_STRING; /* Back to string absorption. */
- }
- }
- #endif /* NOESCSEQ */
- #endif /* NOCSETS */
-
- int i, active; /* Variables global to this module */
- static char *p;
-
- static char *ibp; /* Input buffer pointer */
- static int ibc = 0; /* Input buffer count */
- #define IBUFL 1024 /* Input buffer length */
-
- static char *obp; /* Output buffer pointer */
- static int obc = 0; /* Output buffer count */
- #define OBUFL 1024 /* Output buffer length */
-
- #ifdef DYNAMIC
- static char *ibuf, *obuf; /* Line and temp buffers */
- #else
- static char ibuf[IBUFL], obuf[OBUFL];
- #endif /* DYNAMIC */
-
- char kbuf[10], *kbp; /* Keyboard buffer */
-
- /* C O N E C T -- Perform terminal connection */
-
- int inshift, outshift; /* SO/SI shift states */
-
- /* C K C P U T C -- C-Kermit CONNECT Put Character to Screen */
- /*
- Output is buffered to avoid slow screen writes on fast connections.
- */
- int
- ckcputf() { /* Dump the output buffer */
- int x;
- if (obc > 0) /* If we have any characters, */
- x = conxo(obc,obuf); /* dump them, */
- obp = obuf; /* reset the pointer */
- obc = 0; /* and the counter. */
- return(x); /* Return conxo's return code */
- }
-
- int
- ckcputc(c) int c; {
- int x;
-
- *obp++ = c & 0xff; /* Deposit the character */
- obc++; /* Count it */
- if (ibc == 0 || /* If input buffer empty */
- obc == OBUFL) { /* or output buffer full */
- x = conxo(obc,obuf); /* dump the buffer, */
- obp = obuf; /* reset the pointer */
- obc = 0; /* and the counter. */
- return(x); /* Return conxo's return code */
- } else return(0);
- }
-
- /* C K C G E T C -- C-Kermit CONNECT Get Character */
- /*
- Buffered read from communication device.
- Returns the next character, refilling the buffer if necessary.
- On error, returns ttinc's return code (see ttinc() description).
- Dummy argument for compatible calling conventions with ttinc().
- */
- int
- ckcgetc(dummy) int dummy; {
- int c, n;
-
- if (ibc > 0) { /* Have buffered port characters */
- src = 1; /* Say source is port */
- c = *ibp++ & 0xff; /* Get next character */
- ibc--; /* Reduce input buffer count */
- debug(F101,"CKCGETC returns buffered port char","",c);
- return(c); /* Return buffered port character */
- } else { /* Need to refill buffer */
- contti(&c, &src); /* Read one character */
- if (src < 0) { /* If error, return error code */
- return(src);
- } else if (src == 0) { /* Got a character from the keyboard */
- debug(F101,"CKCGETC returns keyboard char","",c);
- return(c);
- } else { /* Got a port character */
- ibp = ibuf; /* Reset buffer pointer */
- *ibp++ = c; /* Deposit the character */
- ibc++; /* and count it */
- if ((n = ttchk()) > 0) { /* Any more characters waiting? */
- if (n > (IBUFL - ibc)) /* Get them all at once. */
- n = IBUFL - ibc; /* Don't overflow the buffer */
- if ((n = ttxin(n,(CHAR *)ibp)) > 0) /* Read waiting chars */
- ibc += n; /* Advance counter */
- }
- ibp = ibuf; /* Reset buffer pointer again */
- c = *ibp++ & 0xff; /* Get first character from buffer */
- ibc--; /* Reduce buffer count */
- debug(F101,"CKCGETC returns port char","",c);
- return(c); /* Return the character */
- }
- }
- }
-
- int
- conect() {
- int c; /* c is a character, but must be signed
- integer to pass thru -1, which is the
- modem disconnection signal, and is
- different from the character 0377 */
- int c2, csave; /* Copies of c */
- char errmsg[50], *erp, *cp;
- int n, x; /* Workers */
-
- if (!local) {
- #ifdef NETCONN
- printf("Sorry, you must SET LINE or SET HOST first\n");
- #else
- printf("Sorry, you must SET LINE first\n");
- #endif /* NETCONN */
- return(-2);
- }
- if (batch || backgrd) {
- printf(
- "\r\nSorry, Kermit's CONNECT command can be used only in the foreground\r\n");
- return(0);
- }
- #ifdef TCPSOCKET
- if (network && (nettype != NET_TCPB)) {
- printf("Sorry, network type not supported yet\n");
- return(0);
- }
- #endif /* TCPSOCKET */
-
- if (speed < 0 && network == 0) {
- printf("Sorry, you must SET SPEED first\n");
- return(-2);
- }
- if ((escape < 0) || (escape > 0177)) {
- printf("Your escape character is not ASCII - %d\n",escape);
- return(-2);
- }
- if (ttyfd < 0) { /* If communication device not open */
- debug(F111,"ckvcon opening",ttname,0); /* Open it now. */
- if (ttopen(ttname,
- &local,
- network ? -nettype : mdmtyp,
- 0
- ) < 0) {
- erp = errmsg;
- sprintf(erp,"Sorry, can't open %s",ttname);
- perror(errmsg);
- debug(F110,"ckvcon open failure",errmsg,0);
- return(-2);
- }
- }
- if (!quiet) {
- #ifdef NETCONN
- if (network) {
- printf("\nConnecting to host %s",ttname);
- } else {
- #endif /* NETCONN */
- printf("\nConnecting to %s",ttname);
- if (speed > -1L) printf(", speed %ld",speed);
- #ifdef NETCONN
- }
- #endif /* NETCONN */
- printf(".\r\nThe escape character is %s (ASCII %d).\r\n",
- dbchr(escape),escape);
- printf("Type the escape character followed by C to get back,\r\n");
- printf("or followed by ? to see other options.\r\n");
- if (seslog) {
- printf("(Session logged to %s)\r\n",sesfil);
- }
- if (debses) printf("Debugging Display...)\r\n");
- printf("\r\n");
- }
-
- /* Condition console terminal and communication line */
-
- if (conbin(escape) < 0) {
- printf("Sorry, can't condition console terminal\n");
- return(-2);
- }
- if (ttvt(speed,flow) < 0) {
- /* tthang(); */ /* Closing it should be quite enough! */
- ttclos(0);
- if (ttopen(ttname, /* Open it again... */
- &local,
- network ? -nettype : mdmtyp,
- 0
- ) < 0) {
- erp = errmsg;
- sprintf(erp,"Sorry, can't reopen %s",ttname);
- perror(errmsg);
- return(0);
- }
- if (ttvt(speed,flow) < 0) { /* Try virtual terminal mode again. */
- conres(); /* Failure this time is fatal. */
- printf("Sorry, Can't condition communication line\n");
- return(0);
- }
- }
- debug(F101,"connect ttvt ok, escape","",escape);
-
- #ifndef NOCSETS
- /* Set up character set translations */
-
- #ifdef KANJI
- /* Kanji not supported yet */
- if (fcsinfo[tcsr].alphabet == AL_JAPAN ||
- fcsinfo[tcsl].alphabet == AL_JAPAN ) {
- tcs = TC_TRANSP;
- } else
- #endif /* KANJI */
- #ifdef CYRILLIC
- if (fcsinfo[tcsl].alphabet == AL_CYRIL) {
- tcs = TC_CYRILL;
- } else
- #endif /* CYRILLIC */
- tcs = TC_1LATIN;
-
- if (tcsr == tcsl) { /* Remote and local sets the same? */
- sxo = rxo = NULL; /* If so, no translation. */
- sxi = rxi = NULL;
- } else { /* Otherwise, set up */
- sxo = xls[tcs][tcsl]; /* translation function */
- rxo = xlr[tcs][tcsr]; /* pointers for output functions */
- sxi = xls[tcs][tcsr]; /* and for input functions. */
- rxi = xlr[tcs][tcsl];
- }
- /*
- This is to prevent use of zmstuff() and zdstuff() by translation functions.
- They only work with disk i/o, not with communication i/o. Luckily Russian
- translation functions don't do any stuffing...
- */
- langsv = language;
- #ifndef NOCYRIL
- if (language != L_RUSSIAN)
- #endif /* NOCYRIL */
- language = L_USASCII;
-
- #ifdef SKIPESC
- /*
- We need to activate the "skip escape sequence" feature when:
- (a) translation is elected, and
- (b) the local and/or remote set is 7-bit set other than US or UK ASCII.
- */
- skipesc = (tcs != TC_TRANSP) && /* Not transparent */
- (fcsinfo[tcsl].size == 128 || fcsinfo[tcsr].size == 128) && /* 7 bits */
- (fcsinfo[tcsl].code != FC_USASCII) && /* Not US ASCII */
- (fcsinfo[tcsl].code != FC_UKASCII); /* Not UK ASCII */
- inesc = ES_NORMAL; /* Initial state of recognizer */
- #ifdef COMMENT
- debug(F101,"tcs","",tcs);
- debug(F101,"tcsl","",tcsl);
- debug(F101,"tcsr","",tcsr);
- debug(F101,"fcsinfo[tcsl].size","",fcsinfo[tcsl].size);
- debug(F101,"fcsinfo[tcsr].size","",fcsinfo[tcsr].size);
- #endif /* COMMENT */
- debug(F101,"skipesc","",skipesc);
- #endif /* SKIPESC */
- #endif /* NOCSETS */
-
- #ifdef DYNAMIC
- if (!(ibuf = malloc(IBUFL+1))) { /* Allocate input line buffer */
- printf("Sorry, CONNECT input buffer can't be allocated\n");
- return(0);
- }
- if (!(obuf = malloc(OBUFL+1))) { /* Allocate input line buffer */
- printf("Sorry, CONNECT output buffer can't be allocated\n");
- free(ibuf);
- return(0);
- }
- #endif /* DYNAMIC */
-
- inshift = outshift = 0; /* Initial SI/SO states */
- ibp = ibuf; /* Input and output buffers */
- ibc = 0;
- obp = obuf;
- obc = 0;
- active = 1;
-
- do { /* Top of big loop */
- #ifndef NOSETKEY
- /*
- Before reading anything from the keyboard, continue expanding the current
- active keyboard macro, if any.
- */
- if (kmptr) { /* Have active macro */
- src = 0; /* Pretend char came from keyboard */
- if ((c = (CHAR) *kmptr++) == NUL) { /* but get it from the macro */
- kmptr = NULL; /* If no more chars in macro, */
- continue; /* reset pointer and continue. */
- }
- } else /* OTHERWISE... */
- #endif /* NOSETKEY */
- /*
- contti() samples the keyboard and the communication device, in that order,
- in what amounts to a busy loop, and does not return until it has something
- from one or the other. This drives the VAX crazy, and also gives very poor
- performance: input is character-at a time, and the keyboard buffer is
- checked at least once for every character that comes in from the remote.
- Somebody who knows something about VMS, PLEASE FIND A BETTER WAY.
-
- We want a version of contti() that does what select() does in BSD, and we
- also want it to be buffered internally, so it doesn't have to call the
- operating system for every single input character. And most of all we don't
- want it to run a busy loop all the time. No doubt this involves ASTs and
- QIOs, things of which I know nothing.
- */
- c = ckcgetc(0); /* Calls contti()... */
- /*
- Get here with a character in c, and:
-
- src = -1 Communication error
- 1 Character from comm line
- 0 Character from console
- */
-
- if (src < 0) { /* Comm line hangup or other error */
- /*
- We should check WHY src < 0 and not just dive under for ANY reason.
- */
- if (!quiet) printf("\r\nCommunications disconnect ");
- active = 0;
- } else if (!src) {
- /*
- Character from console
- */
- c &= cmdmsk; /* Do requested masking */
- #ifndef NOICP
- #ifndef NOSETKEY
- /*
- Note: kmptr is NULL if we got character c from the keyboard, and it is
- not NULL if it came from a macro. In the latter case, we must avoid
- expanding it again.
- */
- if (!kmptr && macrotab[c]) { /* If a macro is assigned to it */
- kmptr = macrotab[c]; /* set up the pointer */
- continue; /* and do this again. */
- } else c = keymap[c]; /* Else use single-char keymap */
- #endif /* NOSETKEY */
- #endif /* NOICP */
- csave = c;
- if (
- #ifndef NOICP
- #ifndef NOSETKEY
- !kmptr &&
- #endif /* NOSETKEY */
- #endif /* NOICP */
- ((c & 0x7f) == escape)) { /* Escape character? */
- conresne(); /* Restore to normal attributes */
- c = coninc(0) & 0177;
- doesc(c);
- conbin(escape);
- } else { /* Ordinary character */
- #ifndef NOCSETS
- #ifndef SKIPESC
- /* Translate character sets */
- if (sxo) c = (*sxo)(c); /* From local to intermediate. */
- if (rxo) c = (*rxo)(c); /* From intermediate to remote. */
- #else
- if (inesc == ES_NORMAL) { /* If not inside escape seq.. */
- /* Translate character sets */
- if (sxo) c = (*sxo)(c); /* Local to intermediate. */
- if (rxo) c = (*rxo)(c); /* Intermediate to remote. */
- }
- if (skipesc) chkaes(c); /* Check escape sequence status */
- #endif /* SKIPESC */
- #endif /* NOCSETS */
- /*
- If Shift-In/Shift-Out is selected and we have a 7-bit connection,
- handle shifting here.
- */
- if (sosi) { /* Shift-In/Out selected? */
- if (cmask == 0177) { /* In 7-bit environment? */
- if (c & 0200) { /* 8-bit character? */
- if (outshift == 0) { /* If not shifted, */
- if (ttoc(dopar(SO)) < 0) { /* shift. */
- active = 0;
- continue;
- }
- outshift = 1;
- }
- } else {
- if (outshift == 1) { /* 7-bit character */
- if (ttoc(dopar(SI)) < 0) { /* If shifted, */
- active = 0;
- continue;
- }
- outshift = 0; /* unshift. */
- }
- }
- }
- if (c == SO) outshift = 1; /* User typed SO */
- if (c == SI) outshift = 0; /* User typed SI */
- }
- c &= cmask; /* Apply Kermit-to-host mask now. */
-
- /* If we have a CR, handle CR/CRLF mapping... */
-
- if (c == '\015') {
- if (tnlm /* TERMINAL NEWLINE ON */
- #ifdef TNCODE /* And for TELNET... */
- || (network && ttnproto == NP_TELNET)
- #endif /* TNCODE */
- ) {
- ttoc(dopar('\015')); /* Send CR */
- if (duplex) conoc('\015'); /* Maybe echo CR */
- #ifdef TNCODE
- if (network && !tn_nlm && ttnproto == NP_TELNET)
- c = '\0'; /* Stuff NUL */
- else
- #endif /* TNCODE */
- c = '\012'; /* Stuff LF */
- csave = c;
- }
- } /* Now process the LF or NUL... */
- #ifdef TNCODE
- /* If user types the 0xff character (TELNET IAC), it must be doubled. */
- else
- if (c == IAC && network && ttnproto == NP_TELNET) {
- /* Send one copy now */
- ttoc(IAC); /* and the other one just below. */
- }
- #endif /* TNCODE */
- if (ttoc(dopar(c)) < 0) { /* Now send the character. */
- active = 0;
- continue;
- }
- if (duplex) { /* Half duplex? */
- if (debses) /* Yes, echo locally */
- conol(dbchr(csave)); /* in appropriate mode */
- else
- conoc(csave);
- if (seslog) zchout(ZSFILE,c); /* And maybe log it. */
- }
- }
- } else {
- /*
- Character from comm. line
- */
- #ifdef TNCODE
- /* Handle telnet options */
- if (network && nettype == NP_TELNET && ((c & 0xff) == IAC)) {
- ckcputf(); /* Dump output buffer */
- if ((x = tn_doop(c & 0xff, duplex, ckcgetc)) == -1 && !quiet)
- printf("\r\nCommunications disconnect ");
- if (x == 1) duplex = 1; /* Change duplex if necessary. */
- if (x == 2) duplex = 0;
- continue; /* Negotiation OK, go get next char. */
- }
- #endif /* TNCODE */
- if (debses) { /* Output character to screen */
- char *s; /* Debugging display... */
- s = dbchr(c);
- while (*s)
- ckcputc(*s++);
- } else { /* or regular... */
- c &= cmask; /* Do first masking */
- if (sosi) { /* Handle SI/SO */
- if (c == SO) { /* Shift Out */
- inshift = 1;
- continue;
- } else if (c == SI) { /* Shift In */
- inshift = 0;
- continue;
- }
- if (inshift) c |= 0200;
- }
- #ifndef NOCSETS
- #ifndef SKIPESC
- if (sxi) c = (*sxi)(c); /* Xlate char sets */
- if (rxi) c = (*rxi)(c);
- #else
- if (inesc == ES_NORMAL) {
- if (sxi) c = (*sxi)(c);
- if (rxi) c = (*rxi)(c);
- }
- if (skipesc) chkaes(c); /* Esc seq status */
- #endif /* SKIPESC */
- #endif /* NOCSETS */
- c &= cmdmsk; /* Apply mask */
- if (c == CR && tt_crd) { /* SET TERM CR-DISPLAY CRLF ? */
- ckcputc(c); /* Yes, output CR */
- if (seslog) zchout(ZSFILE,c);
- c = LF; /* and insert a linefeed */
- }
- ckcputc(c); /* Put it on the screen. */
- if (seslog) zchout(ZSFILE,c); /* If logging, log it. */
- }
- }
- } while (active);
- cancio();
- conres();
- if (!quiet)
- printf("\r\n(Back at %s)\r\n",
- *myhost ? myhost : "local VMS system");
- what = W_NOTHING;
- #ifndef NOCSETS
- language = langsv; /* Restore language */
- #endif /* NOCSETS */
- return(1);
- }
-
- /* H C O N N E -- Give help message for connect. */
-
- VOID
- hconne() {
- int c;
- static char *hlpmsg[] = {
- "\n",
- " C to return to C-Kermit prompt, H to hangup and close the connection,\n",
- " B to send a BREAK, L to send a Long BREAK,\n",
- #ifdef TNCODE
- " A to send TELNET Are You There, I to send TELNET Interrupt,\n",
- #endif /* TNCODE */
- " 0 (zero) to send a null, X to send an XON,\n",
- #ifdef NOPUSH
- " S for status of connection, ? for this message, or:\n",
- #else
- " @ to enter DCL, S for status of connection,\n",
- " ? for this message, or:\n",
- #endif /* NOPUSH */
- " \\ to begin a backslash escape:\n",
- " \\nnn (decimal character code)\n",
- " \\Onnn (octal character code)\n",
- " \\Xhh (hexadecimal character code)\n",
- " Terminate with carriage return.\n\n",
- " Type the escape character again to send the escape character, or\n",
- " press the space-bar to resume the CONNECT command.\n\n",
- "" };
- /*
- Need to save term characteristics/ allow disable binary mode
- print message, get text and then restore previous state.
- */
- conol("\r\nPress C to return to ");
- conol(*myhost ? myhost : "the C-Kermit prompt");
- conoll(", or:");
- conola(hlpmsg); /* Print the help message. */
- conol("Command>"); /* Prompt for command. */
- c = coninc(0) & 0x7f;
- conoc(c); /* Echo it. */
- if (c != CMDQ)
- conoll("");
- doesc(c);
- }
-
- /* D O E S C -- Process an escape character argument */
-
- VOID
- #ifdef CK_ANSIC
- doesc(register unsigned char c)
- #else
- doesc(c) register unsigned char c;
- #endif /* CK_ANSIC */
- /* doesc() */ {
- int d;
- char sbuf[35];
-
- c &= 0177; /* Mask off 8th bit */
-
- if (c == escape) { /* If it's the escape character, */
- d = dopar(c); /* just send it. */
- ttoc(d);
- return;
- }
- if (isupper(c)) c = tolower(c); /* Convert to lowercase letter. */
- if (iscntrl(c)) c += 'a' - '\001';
-
- switch (c) { /* Take requested action. */
- case 'b':
- ttsndb(); /* Send a BREAK signal */
- break;
- #ifdef TNCODE
- case 'i': /* Send TELNET interrupt */
- #ifndef IP
- #define IP 244
- #endif /* IP */
- if (network && ttnproto == NP_TELNET) { /* TELNET */
- CHAR temp[3];
- temp[0] = IAC; /* I Am a Command */
- temp[1] = IP; /* Interrupt Process */
- temp[2] = NUL;
- ttol((CHAR *)temp,2);
- } else conoc(BEL);
- break;
- case 'a': /* "Are You There?" */
- case '\01':
- #ifndef AYT
- #define AYT 246
- #endif /* AYT */
- if (network && ttnproto == NP_TELNET) {
- CHAR temp[3];
- temp[0] = IAC; /* I Am a Command */
- temp[1] = AYT; /* Are You There? */
- temp[2] = NUL;
- ttol((CHAR *)temp,2);
- } else conoc(BEL);
- #endif /* TNCODE */
- break;
- case 'c': /* Return to prompt */
- active = 0;
- conol("\r\n");
- break;
- case 'h': /* Hang up the connection */
- #ifndef NODIAL
- if (mdmhup() < 1) /* Try via modem first, otherwise */
- #endif /* NODIAL */
- tthang(); /* the old-fashioned way. */
- conol("\r\nHanging up ");
- break;
- case 'l': /* Send a Long BREAK signal */
- ttsndlb();
- break;
- case 's': /* Status */
- sprintf(sbuf,"Connected thru %s",ttname);
- conol(sbuf);
- sprintf(sbuf,", speed: %d",speed);
- conol(sbuf);
- if (seslog) {
- sprintf(sbuf,", logging file: %s",sesfil);
- conol(sbuf);
- }
- conoll("");
- break;
- #ifndef NOPUSH
- case '!':
- case '@':
- conres(); /* Put console back to normal */
- zshcmd(""); /* Start DCL. */
- if (conbin(escape) < 0) {
- printf("Error returning to remote session\n");
- active = 0;
- }
- return;
- #endif /* NOPUSH */
-
- case 'x': /* XON */
- /*
- NOTE: Here we should also issue QIO's to clear XOFF deadlock.
- */
- ttoc(dopar(XON));
- break;
- case '?': /* Give Help */
- hconne();
- break;
- case '0': /* Send a NULL */
- c = '\0';
- d = dopar(c);
- ttoc(d);
- break;
- case SP: /* Ignore space */
- break;
- default:
- if (c == CMDQ) { /* Backslash escape */
- int x;
- kbp = kbuf;
- *kbp++ = c;
- while (((c = (coninc(0) & cmdmsk)) != '\r') && (c != '\n'))
- *kbp++ = c;
- *kbp = NUL; kbp = kbuf;
- x = xxesc(&kbp);
- if (x >= 0) {
- c = dopar(x);
- ttoc(c);
- return;
- } else {
- conoc(BEL);
- return;
- }
- }
- conoc(BEL); return; /* Invalid esc arg, beep */
- }
- }
-